#include "Lightswitch.h"

using namespace std;

/*
 * Esta es una implementación del patrón de semáforos Lightswitch,
 * presentado por Allen B. Downey en The Little Book of Semaphores,
 * página 76.
 *
 * Su nombre se debe a una analogía con la situación en la
 * cual una persona entra primera a una habitación y prende la luz,
 * mientras que la última persona en salir la apaga.
 */

Lightswitch::Lightswitch() {
	this->contador = 0;
	this->mutex = new Semaphore(1); // Se podría utiliza un Mutex* directamente,
	 	  	  	  	  	  	  	    // pero usamos un semáforo inicializado en 1.	 	  	  	  	  	  	  	  	// de Allen B. Downey en vez de lock y unlock.
}

Lightswitch::~Lightswitch() {
	delete this->mutex;
}

void Lightswitch::lock(Semaphore* semaphore) {
	this->mutex->wait();

	++this->contador;

	if (this->contador == 1) {
		semaphore->wait();
	}

	this->mutex->signal();
}

void Lightswitch::unlock(Semaphore* semaphore) {
	this->mutex->wait();

	--this->contador;

	if (this->contador == 0) {
		semaphore->signal();
	}

	this->mutex->signal();
}
